package com.enation.app.javashop.core.distribution.service.impl;

import com.dag.eagleshop.core.account.model.dto.member.MemberDTO;
import com.enation.app.javashop.core.base.rabbitmq.AmqpExchange;
import com.enation.app.javashop.core.client.member.MemberClient;
import com.enation.app.javashop.core.distribution.exception.DistributionErrorCode;
import com.enation.app.javashop.core.distribution.exception.DistributionException;
import com.enation.app.javashop.core.distribution.model.dos.*;
import com.enation.app.javashop.core.distribution.model.dto.DistributionDTO;
import com.enation.app.javashop.core.distribution.model.dto.QueryShareInfoDTO;
import com.enation.app.javashop.core.distribution.model.dto.ShareDTO;
import com.enation.app.javashop.core.distribution.model.enums.DistributionConstants;
import com.enation.app.javashop.core.distribution.model.enums.FansDataKeyEnum;
import com.enation.app.javashop.core.distribution.model.enums.SettleModeEnum;
import com.enation.app.javashop.core.distribution.model.enums.UpgradeTypeEnum;
import com.enation.app.javashop.core.distribution.model.vo.DistributionRelationshipVO;
import com.enation.app.javashop.core.distribution.model.vo.DistributionVO;
import com.enation.app.javashop.core.distribution.model.vo.FansDataVO;
import com.enation.app.javashop.core.distribution.service.*;
import com.enation.app.javashop.core.distribution.service.pattern.DistributionContext;
import com.enation.app.javashop.core.distribution.service.pattern.DistributionMemberFocusStrategy;
import com.enation.app.javashop.core.distribution.service.pattern.DistributionSelfTakeFocusStrategy;
import com.enation.app.javashop.core.distribution.service.pattern.DistributionStrategy;
import com.enation.app.javashop.core.goods.GoodsErrorCode;
import com.enation.app.javashop.core.goods.model.dos.GoodsDO;
import com.enation.app.javashop.core.goods.service.GoodsQueryManager;
import com.enation.app.javashop.core.member.model.dos.BuyerLastLeaderDO;
import com.enation.app.javashop.core.member.model.dos.LeaderDO;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.vo.MemberInviterVO;
import com.enation.app.javashop.core.member.model.enums.CommissionTypeEnum;
import com.enation.app.javashop.core.member.model.vo.LeaderVO;
import com.enation.app.javashop.core.member.service.LeaderFansManager;
import com.enation.app.javashop.core.member.service.LeaderManager;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.orderbill.model.dos.BillItem;
import com.enation.app.javashop.core.orderbill.model.enums.BillType;
import com.enation.app.javashop.core.orderbill.service.BillItemManager;
import com.enation.app.javashop.core.promotion.shetuan.model.dos.ShetuanOrderDO;
import com.enation.app.javashop.core.promotion.shetuan.model.vo.DistributionFansOrderVO;
import com.enation.app.javashop.core.promotion.shetuan.service.ShetuanGoodsManager;
import com.enation.app.javashop.core.promotion.shetuan.service.ShetuanManager;
import com.enation.app.javashop.core.promotion.shetuan.service.ShetuanOrderManager;
import com.enation.app.javashop.core.trade.order.model.dos.OrderDO;
import com.enation.app.javashop.core.trade.order.model.dos.OrderProfitDO;
import com.enation.app.javashop.core.trade.order.model.enums.OrderTypeEnum;
import com.enation.app.javashop.core.trade.order.service.OrderProfitManager;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.util.*;
import com.enation.app.javashop.framework.util.CurrencyUtil;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.IDataUtils;
import com.enation.app.javashop.framework.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.assertj.core.util.Lists;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 分销管理实现类
 */
@Component
public class DistributionManagerImpl implements DistributionManager {

    protected final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    private CommissionTplManager commissionTplManager;
    @Autowired
    private UpgradeLogManager upgradeLogManager;
    @Autowired
    private MemberClient memberClient;
    @Autowired
    private GoodsQueryManager goodsQueryManager;
    @Autowired
    private ShetuanOrderManager shetuanOrderManager;
    @Autowired
    private ShetuanGoodsManager shetuanGoodsManager;
    @Autowired
    private DistributionGoodsManager distributionGoodsManager;
    @Autowired
    private ShetuanManager shetuanManager;
    @Autowired
    @Qualifier("distributionDaoSupport")
    private DaoSupport daoSupport;
    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport tradeDaoSupport;
    @Autowired
    private LeaderFansManager leaderFansManager;
    @Autowired
    private LeaderManager leaderManager;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private DistributionOrderManager distributionOrderManager;
    @Autowired
    private BillItemManager billItemManager;
    @Autowired
    private OrderProfitManager orderProfitManager;
    @Autowired
    private AmqpTemplate amqpTemplate;

    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");

    @Override
    public DistributionDO add(DistributionDO distributor) {
        // 如果分销商值有效
        if (distributor != null) {
            distributor.setCreateTime(DateUtil.getDateline());
            this.daoSupport.insert("es_distribution", distributor);
        }
        distributor.setId(daoSupport.getLastId("es_distribution"));
        return distributor;
    }

    /**
     * 所有下线
     */
    @Override
    public List<DistributionVO> allDown(Integer memberId) {
        List<DistributionDO> dos = this.daoSupport.queryForList("select * from es_distribution where member_id_lv1 =? or member_id_lv2 = ?", DistributionDO.class, memberId, memberId);


        List<DistributionVO> vos = new ArrayList<>();
        //填充一级
        for (DistributionDO ddo : dos) {
            if (ddo.getMemberIdLv1().equals(memberId)) {
                vos.add(new DistributionVO(ddo));
            }
        }
        //填充二级

        if (!vos.isEmpty()) {
            for (DistributionDO ddo : dos) {
                for (DistributionVO vo : vos) {
                    if (ddo.getMemberIdLv1().equals(vo.getId())) {
                        List<DistributionVO> item = vo.getItem();
                        if (item == null) {
                            item = new ArrayList<>();
                        }
                        item.add(new DistributionVO(ddo));
                        vo.setItem(item);
                    }
                }
            }
        }

        return vos;


    }

    @Override
    public Page page(Integer pageNo, Integer pageSize, DistributionVO distributionVO) {

        List<String> params = new ArrayList<>();
        StringBuffer sql = new StringBuffer("select d.*, m.real_name, m.midentity, m.mobile, m.nickname,esm.real_name as lv1_real_name,esm.mobile as lv1_mobile from es_distribution d left join es_member m on m.member_id = d.member_id " +
                " left join es_member esm on d.member_id_lv1 = esm.member_id ");
        sql.append(" where d.audit_status != 0");

        //   省 地址查询
        Integer provinceId = distributionVO.getProvinceId();
        if (provinceId != null && provinceId != 0) {
            sql.append(" and d.province_id = ?");
            params.add(provinceId.toString());
        }

        //   市地址查询
        Integer cityId = distributionVO.getCityId();
        if (cityId != null && cityId != 0) {
            sql.append(" and d.city_id = ?");
            params.add(cityId.toString());
        }
        if (StringUtils.isNotEmpty(distributionVO.getCity())) {
            sql.append(" and ( d.province = ? or d.city=?)");
            params.add(distributionVO.getCity());
            params.add(distributionVO.getCity());
        }

        //   区/县 地址查询
        Integer countyId = distributionVO.getCountyId();
        if (countyId != null && countyId != 0) {
            sql.append(" and d.county_id = ?");
            params.add(countyId.toString());
        }

        // 上级团长真实姓名
        String  lv1RealName= distributionVO.getLv1RealName();
        if (!StringUtil.isEmpty(lv1RealName)) {
            sql.append(" and esm.real_name like ?");
            params.add("%" + lv1RealName + "%");
        }

        //  团长手机号
        String mobile = distributionVO.getMobile();
        if (!StringUtil.isEmpty(mobile)) {
            sql.append(" and m.mobile = ?");
            params.add(mobile);
        }

        //  团长等级
        Integer distributorGrade = distributionVO.getDistributorGrade();
        if (distributorGrade != null  ) {
            sql.append(" and d.distributor_grade = ?");
            params.add(distributorGrade.toString());
        }

        //  审核状态
        Integer auditStatus = distributionVO.getAuditStatus();
        if (auditStatus != null ) {
            sql.append(" and d.audit_status = ?");
            params.add(auditStatus.toString());
        }

        //  结算模式
        Integer settleMode = distributionVO.getSettleMode();
        if (settleMode != null ) {
            sql.append(" and d.settle_mode = ?");
            params.add(settleMode.toString());
        }

        //  业务类型
        Integer businessType = distributionVO.getBusinessType();
        if (businessType != null ) {
            sql.append(" and d.business_type = ?");
            params.add(businessType.toString());
        }

        // 会员名称
        String realName = distributionVO.getRealName();
        if (!StringUtil.isEmpty(realName)) {
            sql.append(" and m.real_name like ?");
            params.add("%" + realName + "%");
        }
        // 会员昵称
        String nickName = distributionVO.getNickName();
        if (!StringUtil.isEmpty(nickName)) {
            sql.append(" and m.nickname like ?");
            params.add("%" + nickName + "%");
        }
        sql.append(" order by d.id desc");
        Page<DistributionDTO> page = this.daoSupport.queryForPage(sql.toString(), pageNo, pageSize, DistributionDTO.class, params.toArray());

        Page result = new Page();
        result.setPageNo(page.getPageNo());
        result.setPageSize(page.getPageSize());
        result.setDataTotal(page.getDataTotal());

        List<DistributionVO> vos = new ArrayList<>();
        for (DistributionDTO ddo : page.getData()) {
            vos.add(new DistributionVO(ddo));
        }
        result.setData(vos);
        return result;
    }

    @Override
    public DistributionDO getDistributorByMemberId(Integer memberId) {

        String sql = "SELECT * FROM es_distribution where member_id = ?";
        DistributionDO distributor = this.daoSupport.queryForObject(sql, DistributionDO.class, memberId);

        return distributor;
    }

    @Override
    public DistributionDO getDistributor(Integer id) {

        String sql = "SELECT * FROM es_distribution where id = ?";
        DistributionDO distributor = this.daoSupport.queryForObject(sql, DistributionDO.class, id);
        return distributor;
    }

    @Override
    public DistributionDO edit(DistributionDO distributor) {

        Map map = new HashMap(16);
        map.put("id", distributor.getId());
        this.daoSupport.update("es_distribution", distributor, map);
        return distributor;

    }


    @Override
    public boolean setParentDistributorId(Integer memberId, Integer parentId) {

        // 如果会员id有效
        if (memberId != 0) {
            // 1.得到父级会员信息 就是当前会员的lv1
            DistributionDO lv1Distributor = this.getDistributorByMemberId(parentId);

            // 2.得到 他的lv1级 （当前会员的lv2级 是他的lv1级的lv1级）
            Integer lv2MemberId = lv1Distributor.getMemberIdLv1();

            // 3.准备拼接sql
            StringBuffer sql = new StringBuffer("UPDATE es_distribution SET member_id_lv1 = ?");

            List<Object> params = new ArrayList<>();
            params.add(lv1Distributor.getMemberId());

            // 如果lv2会员id存在
            if (null != lv2MemberId) {
                sql.append(",member_id_lv2 = ?");
                params.add(lv2MemberId);
            }

            // 4.添加where 并执行
            sql.append(" WHERE member_id = ?");
            params.add(memberId);
            this.daoSupport.execute(sql.toString(), params.toArray());


            this.countDown(lv1Distributor.getMemberId());
            // 如果lv2会员id存在
            if (null != lv2MemberId) {
                this.countDown(lv2MemberId);
            }
            return true;
        }
        return false;
    }

    @Override
    public void addFrozenCommission(Double price, Integer memberId) {
        String sql = "UPDATE es_distribution SET commission_frozen = commission_frozen + ? WHERE member_id = ?";
        this.daoSupport.execute(sql, price, memberId);
    }

    @Override
    public void addTotalPrice(Double orderPrice, Double rebate, Integer memberId) {
        String sql = "UPDATE es_distribution SET turnover_price = turnover_price + ?,rebate_total = rebate_total + ? WHERE member_id = ?";
        this.daoSupport.execute(sql, orderPrice, rebate, memberId);
    }

    @Override
    public void subTotalPrice(Double orderPrice, Double rebate, Integer memberId) {
        String sql = "UPDATE es_distribution SET turnover_price = turnover_price - ?,rebate_total = rebate_total - ? WHERE member_id = ?";
        this.daoSupport.execute(sql, orderPrice, rebate, memberId);
    }

    @Override
    public Double getCanRebate(Integer memberId) {
        try {
            return this.daoSupport
                    .queryForObject("select * from es_distribution where member_id = ?", DistributionDO.class, memberId)
                    .getCanRebate();
        } catch (Exception e) {
            // 如果用户没有提现金额 返回0
            return 0d;
        }
    }

    @Override
    public String getUpMember() {

        String path = this.getDistributorByMemberId(
                UserContext.getBuyer().getUid())
                .getPath();
        String[] up = path.split("\\|");
        Integer upMember = Integer.parseInt(up[up.length - 2]);
        if (upMember == 0) {
            return "没有推荐人";
        }
        try {
            DistributionDO distributor = this.getDistributorByMemberId(upMember);
            Member member = memberClient.getModel(distributor.getMemberId());
            if (member == null) {
                return "没有推荐人";
            }
            return member.getUname();
        } catch (Exception e) {
            return "没有推荐人";
        }
    }

    @Override
    public List<DistributionVO> getLowerDistributorTree(Integer memberId) {
        List<DistributionDO> list = this.daoSupport.queryForList("select * from es_distribution where member_id_lv2 = ? or member_id_lv1 = ? ", DistributionDO.class, memberId, memberId);
        List<DistributionVO> vos = new ArrayList<DistributionVO>();
        for (DistributionDO ddo : list) {
            vos.add(new DistributionVO(ddo));
        }
        List<DistributionVO> result = new ArrayList<>();
        //第一层关系构造
        for (DistributionVO vo : vos) {
            if (vo.getLv1Id().equals(memberId)) {
                result.add(vo);
            }
        }
        //第二层关系构造 循环第一层构造
        for (DistributionVO rs : result) {
            List<DistributionVO> items = new ArrayList<>();
            for (DistributionVO vo : vos) {
                if (rs.getId().equals(vo.getLv1Id())) {
                    items.add(vo);
                }
            }
            rs.setItem(items);
        }
        return result;
    }


    @Override
    public void changeTpl(Integer memberId, Integer tplId) {
        CommissionTpl tpl = commissionTplManager.getModel(tplId);
        DistributionDO ddo = this.getDistributorByMemberId(memberId);
        if (tpl == null || ddo == null) {
            throw new DistributionException(DistributionErrorCode.E1000.code(), DistributionErrorCode.E1000.des());
        }
        this.upgradeLogManager.addUpgradeLog(memberId, tplId, UpgradeTypeEnum.MANUAL);
        this.daoSupport.execute("update es_distribution set current_tpl_id = ? ,current_tpl_name = ? where member_id = ?", tplId, commissionTplManager.getModel(tplId).getTplName(), memberId);
    }

    /**
     * 统计下线人数
     */
    @Override
    public void countDown(Integer memberId) {
        this.daoSupport.execute("UPDATE es_distribution SET downline =(SELECT count from( SELECT count(0) count FROM es_distribution a WHERE a.member_id_lv1 = ? ) counttable ) WHERE member_id = ?", memberId, memberId);
    }


    /**
     *  查询分享内容
     */
    @Override
    public ShareDTO getShareInfo(QueryShareInfoDTO queryShareInfoDTO) {
        Integer id = queryShareInfoDTO.getId();
        Integer shareType = queryShareInfoDTO.getShareType();
        Integer channelType = queryShareInfoDTO.getChannelType();

        ShareDTO shareDTO = new ShareDTO();
        shareDTO.setId(id);
        shareDTO.setChannelType(channelType);
        shareDTO.setShareType(shareType);

        // 小程序
        if(channelType == 1){
            // 商品
            if(shareType == 1){
                GoodsDO goodsDO = goodsQueryManager.getModel(id);
                if(goodsDO == null){
                    throw new ServiceException(GoodsErrorCode.E310.name(), "商品不存在");
                }
                shareDTO.setTitle(goodsDO.getPageTitle());
                shareDTO.setContent(goodsDO.getMetaDescription());
                shareDTO.setImageUrl(goodsDO.getSmall());
                shareDTO.setPath("/pages/goods/goods?goods_id=" + id);
            }else{
                throw new ServiceException(GoodsErrorCode.E310.name(), "暂不支持的分享类型");
            }
        }else{
            throw new ServiceException(GoodsErrorCode.E310.name(), "暂不支持的分享渠道");
        }
        return shareDTO;
    }




    @Override
    public void createShare(String uuid, Integer memberId, String shareKey, String shortUrl) {
        ShareDO shareDO = new ShareDO();
        shareDO.setUuid(uuid);
        shareDO.setMemberId(memberId);
        shareDO.setShareKey(shareKey);
        shareDO.setUrl(shortUrl);
        daoSupport.insert(shareDO);
    }

    @Override
    public ShareDO getByShareKey(String shareKey) {
        String sql = "select * from es_share where share_key = ?";
        return daoSupport.queryForObject(sql, ShareDO.class, shareKey);
    }

    @Override
    public ShareDO getByMemberIdAndUrl(Integer memberId, String shareUrl) {
        String sql = "select * from es_share where member_id = ? and url = ?";
        return daoSupport.queryForObject(sql, ShareDO.class, memberId, shareUrl);
    }


    /**
     * 根据订单计算结算策略
     */
    @Override
    public DistributionStrategy getDistributionStrategy(OrderDO orderDO, DistributionDO buyerDistributor) {
        DistributionStrategy distributionStrategy = null;
        String orderType = orderDO.getOrderType();
        if(orderType.equals(OrderTypeEnum.shetuan.name())||orderType.equals(OrderTypeEnum.pintuan.name())){
            // 一级佣金所得者
            DistributionDO targetDistributor = null;

            // 如果自己是分销商
            if(buyerDistributor.getAuditStatus() == 2 && buyerDistributor.getStatus() == 1){
                targetDistributor = buyerDistributor;
            }else{
                Integer memberIdLv1 = buyerDistributor.getMemberIdLv1();
                if(memberIdLv1 != null){
                    DistributionDO lv1Distributor = getDistributorByMemberId(memberIdLv1);
                    if(lv1Distributor != null && lv1Distributor.getAuditStatus() == 2 && lv1Distributor.getStatus() == 1){
                        targetDistributor = lv1Distributor;
                    }
                }
            }

            // 根据团长自身配置选择结算策略
            if(targetDistributor != null){
                Integer settleMode = targetDistributor.getSettleMode();
                if(settleMode != null){
                    if(settleMode == SettleModeEnum.SELF_TAKE.getIndex()){
                        distributionStrategy = new DistributionSelfTakeFocusStrategy();
                    }else if(settleMode == SettleModeEnum.MEMBER.getIndex()){
                        distributionStrategy = new DistributionMemberFocusStrategy();
                    }
                }
            }

            // 团长没有配置使用默认结算策略
            if(distributionStrategy == null){
                String sellerIds = DictUtils.getDictValue("", "self_take", "distribution_strategy");
                if(!StringUtil.isEmpty(sellerIds)){
                    List<String> sellerIdList = Lists.newArrayList(sellerIds.split(","));
                    if(sellerIdList.contains(String.valueOf(orderDO.getSellerId()))){
                        distributionStrategy = new DistributionSelfTakeFocusStrategy();
                    }
                }
            }
        }

        // 没有任何配置 使用默认结算策略
        if(distributionStrategy == null){
            distributionStrategy = new DistributionMemberFocusStrategy();
        }
        return distributionStrategy;
    }


    /**
     * 计算每个人的分销金额和比例
     */
    @Override
    public void calAllProfit(OrderDO orderDO, DistributionOrderDO distributionOrderDO, DistributionDO buyerDistributor) {
        DistributionStrategy distributionStrategy = getDistributionStrategy(orderDO, buyerDistributor);
        DistributionContext distributionContext = new DistributionContext(distributionStrategy);
        distributionContext.executeCountProfit(orderDO, distributionOrderDO);
    }


    /**
     * 更新退款后剩余收益
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRefundSurplusProfit(OrderDO orderDO, double oldOrderPrice, double newOrderPrice) {
        DistributionOrderDO distributionOrderDO = distributionOrderManager.getModelByOrderSn(orderDO.getSn());

        // 查询明细
        BillItem billItem = billItemManager.getModelByOrderSnAndItemType(orderDO.getSn(), BillType.PAYMENT.name());

        // 退还比例
        double refundScale = BigDecimal.valueOf(newOrderPrice).divide(BigDecimal.valueOf(oldOrderPrice), 6 , BigDecimal.ROUND_HALF_DOWN).doubleValue();

        // 平台佣金
        Double oldPlatformMoney = billItem.getPlatformMoney().doubleValue();
        Double newPlatformMoney = oldPlatformMoney;
        if(newPlatformMoney > 0){
            newPlatformMoney = CurrencyUtil.mul(oldPlatformMoney, refundScale);
        }

        // 邀请佣金
        Double oldInviteRebate = distributionOrderDO.getInviteRebate();
        Double newInviteRebate = oldInviteRebate;
        if(oldInviteRebate > 0){
            newInviteRebate = CurrencyUtil.mul(oldInviteRebate, refundScale);
            distributionOrderDO.setInviteRebate(newInviteRebate);
        }

        // 一级团长佣金
        Double oldGrade1Rebate = distributionOrderDO.getGrade1Rebate();
        Double newGrade1Rebate = oldGrade1Rebate;
        if(oldGrade1Rebate > 0){
            newGrade1Rebate = CurrencyUtil.mul(oldGrade1Rebate, refundScale);
            distributionOrderDO.setGrade1Rebate(newGrade1Rebate);
        }

        // 二级团长佣金
        Double oldGrade2Rebate = distributionOrderDO.getGrade2Rebate();
        Double newGrade2Rebate = oldGrade2Rebate;
        if(oldGrade2Rebate > 0){
            newGrade2Rebate = CurrencyUtil.mul(oldGrade2Rebate, refundScale);
            distributionOrderDO.setGrade2Rebate(newGrade2Rebate);
        }

        // 补贴
        Double oldSubsidyMoney = distributionOrderDO.getSubsidyRebate();
        Double newSubsidyMoney = oldSubsidyMoney;
        if(oldSubsidyMoney > 0){
            newSubsidyMoney = CurrencyUtil.mul(oldSubsidyMoney, refundScale);
            distributionOrderDO.setSubsidyRebate(newSubsidyMoney);
        }

        // 自提点佣金
        Double oldLeaderCommission = 0.0;
        Double newLeaderCommission = 0.0;
        ShetuanOrderDO shetuanOrderDO = shetuanOrderManager.getByOrderId(distributionOrderDO.getOrderId());
        if(shetuanOrderDO != null){
            oldLeaderCommission = shetuanOrderDO.getLeaderCommission();
            newLeaderCommission = oldLeaderCommission;
            if(oldLeaderCommission > 0){
                newLeaderCommission = CurrencyUtil.mul(oldLeaderCommission, refundScale);
            }
            shetuanOrderDO.setLeaderCommission(newLeaderCommission);
            //
            if (newOrderPrice > 0) {
                shetuanOrderDO.setCommissionRate(CurrencyUtil.mul(CurrencyUtil.div(newLeaderCommission, newOrderPrice), 100));
            } else {
                shetuanOrderDO.setCommissionRate(0.0);
            }

            tradeDaoSupport.update(shetuanOrderDO, shetuanOrderDO.getId());
        }

        // 反过来重新计算比例
        if(newOrderPrice > 0){
            distributionOrderDO.setLv1Point(CurrencyUtil.mul(CurrencyUtil.div(newGrade1Rebate, newOrderPrice), 100));
            distributionOrderDO.setLv2Point(CurrencyUtil.mul(CurrencyUtil.div(newGrade2Rebate, newOrderPrice), 100));
            distributionOrderDO.setInvitePoint(CurrencyUtil.mul(CurrencyUtil.div(newInviteRebate, newOrderPrice), 100));
            distributionOrderDO.setSubsidyPoint(CurrencyUtil.mul(CurrencyUtil.div(newSubsidyMoney, newOrderPrice), 100));
        }else{
            distributionOrderDO.setLv1Point(0.0);
            distributionOrderDO.setLv2Point(0.0);
            distributionOrderDO.setInvitePoint(0.0);
            distributionOrderDO.setSubsidyPoint(0.0);
        }

        // 更新分销订单
        distributionOrderManager.edit(distributionOrderDO);

        // 计算卖家收益
        double newOrderPriceIncludeShippingPrice = new BigDecimal(newOrderPrice).add(new BigDecimal(orderDO.getShippingPrice()))
                .setScale(2, BigDecimal.ROUND_HALF_DOWN).doubleValue();
        double sellerSettleMoney = new BigDecimal(newOrderPriceIncludeShippingPrice).subtract(BigDecimal.valueOf(newPlatformMoney))
                .subtract(new BigDecimal(newLeaderCommission)).subtract(BigDecimal.valueOf(newGrade1Rebate)).subtract(BigDecimal.valueOf(newGrade2Rebate))
                .subtract(new BigDecimal(newInviteRebate)).setScale(2, BigDecimal.ROUND_HALF_DOWN).doubleValue();

        billItem.setPlatformMoney(BigDecimal.valueOf(newPlatformMoney));
        billItem.setInviteMoney(BigDecimal.valueOf(newInviteRebate));
        billItem.setLv1Money(BigDecimal.valueOf(newGrade1Rebate));
        billItem.setLv2Money(BigDecimal.valueOf(newGrade2Rebate));
        billItem.setDistributionMoney(BigDecimal.valueOf(CurrencyUtil.add(newGrade1Rebate, newGrade2Rebate)));
        billItem.setLeaderMoney(BigDecimal.valueOf(newLeaderCommission));
        billItem.setSellerMoney(BigDecimal.valueOf(sellerSettleMoney));
        billItem.setSubsidyMoney(BigDecimal.valueOf(newSubsidyMoney));
        billItemManager.edit(billItem, billItem.getId());

        // 查询收益并更新收益
        List<OrderProfitDO> orderProfitList = orderProfitManager.listByOrderId(distributionOrderDO.getOrderId());
        if(orderProfitList != null && !orderProfitList.isEmpty()){
            for (OrderProfitDO orderProfitDO : orderProfitList) {
                Integer commissionType = orderProfitDO.getCommissionType();
                if(commissionType == CommissionTypeEnum.PLATFORM.getIndex()){
                    orderProfitDO.setCommissionMoney(BigDecimal.valueOf(newPlatformMoney));

                }else if(commissionType == CommissionTypeEnum.INVITER.getIndex()){
                    orderProfitDO.setCommissionMoney(BigDecimal.valueOf(newInviteRebate));

                }else if(commissionType == CommissionTypeEnum.DISTRIBUTION.getIndex()){
                    Integer spreadWay = orderProfitDO.getSpreadWay();
                    if(spreadWay == 1){
                        orderProfitDO.setCommissionMoney(BigDecimal.valueOf(newGrade1Rebate));
                    }else if(spreadWay == 2){
                        orderProfitDO.setCommissionMoney(BigDecimal.valueOf(newGrade2Rebate));
                    }

                }else if(commissionType == CommissionTypeEnum.SITE.getIndex()){
                    orderProfitDO.setCommissionMoney(BigDecimal.valueOf(newLeaderCommission));

                }else if(commissionType == CommissionTypeEnum.SUBSIDY.getIndex()){
                    orderProfitDO.setCommissionMoney(BigDecimal.valueOf(newSubsidyMoney));
                }
                orderProfitManager.edit(orderProfitDO);
            }
        }
    }

    /**
     * 随机邀请码
     */
    @Override
    public synchronized String randomInviteCode() {
        Random random = new Random();

        int count = 0;
        while(true){
            count++;
            if(count > 100){
                return "";
            }
            Integer inviteCode = 100000 + random.nextInt(900000);
            String inviteCodeString = String.valueOf(inviteCode);
            DistributionDO distributionDO = getDistributorByInviteCode(inviteCodeString);
            if(distributionDO == null){
                return inviteCodeString;
            }
        }
    }

    @Override
    public DistributionDO getDistributorByInviteCode(String inviteCode) {
        String sql = "SELECT * FROM es_distribution where invite_code = ?";
        return this.daoSupport.queryForObject(sql, DistributionDO.class, inviteCode);
    }

    /**
     * 分页查询我的邀请人 按时间范围
     */
    @Override
    public Page getInviterList(Integer memberId, long startTime, long endTime, Integer pageNo, Integer pageSize){

        StringBuffer sql = new StringBuffer(" SELECT d.create_time AS invite_time, me.nickname AS nickName, me.face, me.mobile FROM es_distribution d " +
                " LEFT JOIN es_member me ON d.member_id = me.member_id " +
                " WHERE d.visit_channel = 6 AND  d.member_id_lv1 = ? ");

        List<Object> params = new ArrayList<>();
        params.add(memberId);
        if (startTime != 0) {
            sql = sql.append(" and d.create_time >= ? ");
            params.add(startTime);
        }

        if (endTime != 0) {
            sql = sql.append(" and d.create_time <= ? ");
            params.add(endTime);
        }
        return this.daoSupport.queryForPage(sql.toString(), pageNo, pageSize, MemberInviterVO.class,params.toArray());
    }

    /**
     * 邀请人排行榜
     */
    @Override
    public Page getRecommendedCouponsRanking(long startTime, long endTime,  Integer pageNo, Integer pageSize) {
        StringBuffer sql = new StringBuffer(" SELECT m.face,m.nickname AS nickName,d.member_id_lv1,count(d.member_id) AS 'inviter_num' " +
                " FROM es_distribution d LEFT JOIN es_member m ON d.member_id_lv1= m.member_id " +
                " WHERE d.visit_channel = 6 AND d.member_id_lv1 != '' ");

        List<Object> params = new ArrayList<>();
        if (startTime != 0) {
            sql = sql.append(" and d.create_time >= ? ");
            params.add(startTime);
        }

        if (endTime != 0) {
            sql = sql.append(" and d.create_time <= ? ");
            params.add(endTime);
        }
        sql.append("GROUP BY d.member_id_lv1 ORDER BY inviter_num desc");
        Page page = this.daoSupport.queryForPage(sql.toString(), pageNo, pageSize, MemberInviterVO.class,params.toArray());
        return page;
    }

    /**
     * 分页查询我的邀请人
     */
    @Override
    public Page loadInviterList(Integer memberId, Integer pageNo, Integer pageSize) {
        String sql = "SELECT UNIX_TIMESTAMP(invite.invite_time) AS invite_time,me.nickname as nickName,me.face,me.mobile from es_member_inviter invite " +
                " LEFT JOIN es_member me ON invite.member_id = me.member_id " +
                " where invite.inviter_member_id = ? ";
        Page page = this.daoSupport.queryForPage(sql, pageNo, pageSize, MemberInviterVO.class, memberId);
        List<MemberInviterVO> list = page.getData();
        for(MemberInviterVO memberInviterVo : list){
            Long inviteTime = memberInviterVo.getInviteTime();
            String inviteTimeStr = DateUtil.toString(inviteTime, "yyyy-MM-dd HH:mm:ss");
            String format = inviteTimeStr+"邀请注册";
            memberInviterVo.setInviteTimeString(format);
        }
        return page;
    }

    /**
     * 分页查询我的粉丝
     */
    @Override
    public Page getMyFansList(Integer memberId, Integer pageNo, Integer pageSize) {
        // 查询当前人的身份 不是团长没有粉丝
        DistributionDO distributionDO = getDistributorByMemberId(memberId);
        if(distributionDO != null){
            if(distributionDO.getAuditStatus() != 2 ){
                return  new Page(pageNo, 0L, pageSize, new ArrayList());
            }
        }
        String  sql = " SELECT di.*,m.nickname,m.face from es_distribution di LEFT JOIN es_member m  " +
                " on di.member_id = m.member_id  where di.member_id_lv1 = ? and audit_status != 2 ";
        Page page = daoSupport.queryForPage(sql,  pageNo, pageSize, DistributionVO.class,memberId);
        List<DistributionVO> list = page.getData();
        for (DistributionVO distributionVO: list) {
            // 一级关系失效时间
            Long lv1ExpireTime = distributionVO.getLv1ExpireTime();
            if(lv1ExpireTime != null){
                // 当前时间
                Long newTime = DateUtil.getDateline();
                // 时间差
                Long timeDifference = lv1ExpireTime - newTime ;
                if(timeDifference != null && timeDifference > 0){
                    Integer ceil = (int)Math.ceil(timeDifference / 86400.0);
                    distributionVO.setDescribe2("锁定期剩余"+ceil+"天");
                }else{
                    distributionVO.setDescribe2("锁定期剩余0天");
                }
            }
            // 查询里面有没有购买时间
            Long lastOrderTime = distributionVO.getLastOrderTime();
            if(lastOrderTime != null){
                String time = DateUtil.toString(lastOrderTime, "yyyy年MM月dd日")+"最后购买";
                distributionVO.setDescribe1(time);
            }else if(distributionVO.getLv1CreateTime() != null){
                String time = DateUtil.toString(distributionVO.getLv1CreateTime(), "yyyy年MM月dd日")+"邀请注册";
                distributionVO.setDescribe1(time);
            }
        }
        return page;
    }

    /**
     * 分页查询我的下级团长
     */
    @Override
    public Page getNextLeaderList(Integer memberId, Integer pageNo, Integer pageSize) {
        // 查询当前人的身份 不是团长没有下级
        DistributionDO distributionDO = getDistributorByMemberId(memberId);
        if(distributionDO != null){
            if(distributionDO.getAuditStatus() != 2 ){
                return  new Page(pageNo, 0L, pageSize, new ArrayList());
            }
        }
        String  sql = " SELECT di.*,m.nickname,m.face," +
                " (SELECT count(1) as downline  from es_distribution esd where esd.member_id_lv1 = di.member_id and esd.audit_status != 2 ) as downline" +
                " from es_distribution di LEFT JOIN es_member m  " +
                " on di.member_id = m.member_id  where di.member_id_lv1 = ? and audit_status = 2 ";
        Page page = daoSupport.queryForPage(sql,  pageNo, pageSize, DistributionVO.class,memberId);
        List<DistributionVO> list = page.getData();
        for (DistributionVO distributionVO : list){
            // 审核时间
            Long auditTime = distributionVO.getAuditTime();
            if(auditTime != null){
                String time = DateUtil.toString(auditTime, "yyyy年MM月dd日")+"成为团长";
                distributionVO.setDescribe1(time);
            }
            Integer downline = distributionVO.getDownline();
            distributionVO.setDescribe2("已推广"+downline+"个粉丝");

        }
        return page;
    }


    /**
     * 我的下级首页查询接口
     */
    @Override
    public Map<String,Object> fansIndex(Integer memberId) {
        Map<String,Object> map= new HashMap<>();
        Page inviterPage = this.loadInviterList(memberId, 1, 1);
        Page fansPage = this.getMyFansList(memberId, 1, 1);
        Page leaderPage = this.getNextLeaderList(memberId, 1, 1);
        // 我的邀请人数量
        map.put("inviterNum", inviterPage.getDataTotal());
        // 我的粉丝数量
        if(fansPage.getData() != null && fansPage.getData().size() > 0){
            map.put("fansNum", fansPage.getDataTotal());
        }else{
            map.put("fansNum", 0);
        }
        // 我的下级团长数量
        if(leaderPage.getData() != null && leaderPage.getData().size() > 0){
            map.put("leaderNum", leaderPage.getDataTotal());
        }else{
            map.put("leaderNum", 0);
        }
        return map;
    }


    /**
     * 查询所有粉丝
     */
    @Override
    public List<DistributionDO> getAllFans() {
        String sql = "SELECT * FROM es_distribution where audit_status != 2 and lv1_expire_time is not null";
        return this.daoSupport.queryForList(sql, DistributionDO.class);
    }

    /**
     * 清除lv1关系
     */
    @Override
    public void removeLv1Relationship(Integer memberId) {
        this.daoSupport.execute("update es_distribution set member_id_lv1 = null, member_id_lv2 = null, lv1_create_time = null, lv1_expire_time = null, lv1_invite_code = null where member_id = ?", memberId);
    }

    /**
     * 我的上级首页查询接口
     */
    @Override
    public Map<String,Object> superiorIndex(Integer memberId) {
        Map<String,Object> map= new HashMap<>();

        LeaderVO leaderVO = new LeaderVO();
        DistributionVO distributionVO = new DistributionVO();

        // 查询我的邀请人
        Member memberInviter = getMemberInviter(memberId);

        // 查询我的自提点
        BuyerLastLeaderDO lastLeaderDO = leaderFansManager.getLastLeader(memberId);

        // 查询出此客户最后绑定的团长关系
        if (lastLeaderDO != null) {
            LeaderDO leaderDO = leaderManager.getById(lastLeaderDO.getLeaderId());
            if (leaderDO != null ) {
                // 自提点的会员
                Member member = memberManager.getModel(leaderDO.getMemberId());
                leaderVO.setSiteName(leaderDO.getSiteName());
                leaderVO.setLeaderName(leaderDO.getLeaderName());
                if(member != null ){
                    leaderVO.setFace(member.getFace());
                }
                StringBuffer describe2 = new StringBuffer();
                String county = leaderDO.getCounty();
                if(StringUtil.notEmpty(county)){
                    leaderVO.setCounty(county);
                    describe2.append(county);
                }
                String street = leaderDO.getStreet();
                if(StringUtil.notEmpty(street)){
                    leaderVO.setStreet(street);
                    describe2.append(street);
                }
                String address = leaderDO.getAddress();
                if(StringUtil.notEmpty(address)){
                    leaderVO.setAddress(address);
                    describe2.append(address);
                }
                leaderVO.setLeaderId(leaderDO.getLeaderId());
                String leaderMobile = leaderDO.getLeaderMobile();
                leaderVO.setLeaderMobile(leaderMobile.substring(0,3)+"****"+leaderMobile.substring(7,leaderMobile.length()));
                leaderVO.setDescribe2(describe2.toString());
                leaderVO.setDescribe1("我的自提点");
            }
        }

        // 查询当前人的身份
        DistributionDO distributionDO = getDistributorByMemberId(memberId);

        // 我的邀请人封装数据
        MemberDTO memberDTO = new MemberDTO();
        if(memberInviter !=null ){
            memberDTO.setMemberId(memberInviter.getMemberId());
            memberDTO.setNickName(memberInviter.getNickname());
            memberDTO.setFace(memberInviter.getFace());
            String mobile = memberInviter.getMobile();
            if(mobile != null){
                memberDTO.setMobile(mobile.substring(0,3)+"****"+mobile.substring(7,mobile.length()));
            }
            memberDTO.setDescribe1("我的邀请人");

        }
        //  我的自提点
        map.put("leaderVO", leaderVO);
        // 我的团长
        map.put("distributionVO", distributionVO);
        // 我的邀请人
        map.put("inviterPage", memberDTO);

        return map;
    }

    // 获取上级团长信息
    @Override
    public Member getSuperiorLeader(Integer memberId){
        DistributionDO currentDistributor = getDistributorByMemberId(memberId);
        if(currentDistributor != null){
            Integer memberIdLv1 = currentDistributor.getMemberIdLv1();
            if(memberIdLv1 != null){
                DistributionDO superiorDistributionDO = getDistributorByMemberId(memberIdLv1);
                if(superiorDistributionDO != null && superiorDistributionDO.getStatus() == 1 && superiorDistributionDO.getAuditStatus() == 2){
                    return memberManager.getModel(memberIdLv1);
                }
            }
        }
        return null;
    }

    /**
     * 邀请我的人
     */
    @Override
    public Member getMemberInviter(Integer memberId){
        String sql ="select m.* from es_member_inviter esi LEFT JOIN es_member m  on esi.inviter_member_id = m. member_id where esi.member_id = ? ";
        return   daoSupport.queryForObject(sql, Member.class, memberId);
    }


    // 查询团长信息
    @Override
    public Page getSuperiorDistribution(String keyWords){
        String sql = " SELECT d.*,m.real_name,m.mobile from es_distribution d  LEFT JOIN es_member m on d.member_id = m.member_id where  " +
                "  (d.invite_code like ?  or m.real_name like ? or m.mobile like ? ) and  d.audit_status = 2  and d.status = 1"  ;
        Integer pageNo = 1;
        Integer pageSize=1000;

        return daoSupport.queryForPage(sql,  pageNo, pageSize, DistributionVO.class,"%"+keyWords+"%","%"+keyWords+"%","%"+keyWords+"%");
    }

    // 修改上级团长
    @Override
    public void updateLv1MemberId(String memberIdss, Integer memberIdLv1) {
        // 查询上级团长的信息判断其有效性
        DistributionDO lv1DistributionDO = this.checkLv1Distribution(memberIdLv1);
        // 查询所选的信息集合
        List<DistributionVO> distributionVOList = this.getdistributionVO(memberIdss);

        if(!CollectionUtils.isEmpty(distributionVOList)){
            List<DistributionRelationshipVO> distributionRelationshipVOList = new ArrayList<>();

            for (DistributionVO distributionVO : distributionVOList){
                // 只能修改团长的上级团长
                if(distributionVO.getAuditStatus() != 2){
                    throw new RuntimeException("只有团长才能设置上级团长");
                }
                Integer memberId = distributionVO.getMemberId();

                if(distributionVO.getLv1Id() != null){
                    // 保存历史团长信息 source = 1 后台修改
                    DistributionRelationshipVO lastDistributionRelationshipVO = buildDistributionRelationshipVO(memberId, distributionVO.getLv1Id(),
                            "团长解绑",1,  null);
                    distributionRelationshipVOList.add(lastDistributionRelationshipVO);
                }

                // 清除lv1关系
                this.removeLv1Relationship(memberId);

                //修改上级团长
                String sql = "update es_distribution set member_id_lv1 = ? , member_id_lv2 = ? , lv1_create_time = ?, lv1_invite_code = ? where member_id = ?";
                long newDateTime = DateUtil.getDateline();
                daoSupport.execute(sql, memberIdLv1, lv1DistributionDO.getMemberIdLv1(), newDateTime, lv1DistributionDO.getInviteCode(), memberId);

                // 保存现在团长信息 source = 1 后台修改
                DistributionRelationshipVO nowDistributionRelationshipVO = buildDistributionRelationshipVO(memberId, lv1DistributionDO.getMemberId(), "团长绑定",
                        1,  null);
                distributionRelationshipVOList.add(nowDistributionRelationshipVO);
            }
            // 保存会员上级团长记录
            amqpTemplate.convertAndSend(AmqpExchange.DISTIRBUTION_BINDING_MESSAGE,
                    AmqpExchange.DISTIRBUTION_BINDING_MESSAGE + "_ROUTING",
                    distributionRelationshipVOList);
        }

    }

    /**
     * 修改普通用户的上级团长
     * 1 后台管理 2 小程序 3 系统自动
     */
    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateNormalMemberLv1MemberId(String memberIds, Integer memberIdLv1,Integer source) {
        // 查询上级团长的信息判断其有效性
        DistributionDO lv1DistributionDO = this.checkLv1Distribution(memberIdLv1);
        // 查询所选的信息集合
        List<DistributionVO> distributionVOList = this.getdistributionVO(memberIds);

        if(!CollectionUtils.isEmpty(distributionVOList)){
            List<DistributionRelationshipVO> distributionRelationshipVOList = new ArrayList<>();
            for (DistributionVO distributionVO : distributionVOList){
                Integer memberId = distributionVO.getMemberId();
                if(distributionVO.getLv1Id() != null){
                    // 保存历史团长信息
                    DistributionRelationshipVO lastDistributionRelationshipVO = buildDistributionRelationshipVO(memberId,
                            distributionVO.getLv1Id(), "团长解绑", source,  null);
                    distributionRelationshipVOList.add(lastDistributionRelationshipVO);
                }

                // 清除lv1关系
                this.removeLv1Relationship(memberId);
                // 修改会员的上级团长
                String sql = "update es_distribution set member_id_lv1 = ? , member_id_lv2 = ? , lv1_create_time = ?, lv1_invite_code = ? where member_id = ?";
                long newDateTime = DateUtil.getDateline();
                daoSupport.execute(sql, memberIdLv1, lv1DistributionDO.getMemberIdLv1(), newDateTime, lv1DistributionDO.getInviteCode(), memberId);

                // 保存现在 会员上级团长记录
                DistributionRelationshipVO nowDistributionRelationshipVO = buildDistributionRelationshipVO(memberId,
                        lv1DistributionDO.getMemberId(), "团长绑定", source, null);
                distributionRelationshipVOList.add(nowDistributionRelationshipVO);

            }
            amqpTemplate.convertAndSend(AmqpExchange.DISTIRBUTION_BINDING_MESSAGE,
                    AmqpExchange.DISTIRBUTION_BINDING_MESSAGE + "_ROUTING",
                    distributionRelationshipVOList);
        }
    }
    //查询上级团长的信息并判断其有效性
    private DistributionDO checkLv1Distribution(Integer memberIdLv1) {
        DistributionDO lv1DistributionDO = this.getDistributorByMemberId(memberIdLv1);
        if(lv1DistributionDO == null){
            throw new RuntimeException("上级团长不存在!");
        }
        if(lv1DistributionDO.getAuditStatus() != 2 && lv1DistributionDO.getStatus() != 1){
            throw new RuntimeException("'上级团长'必须是审核通过的团长并且团长状态为启用!");
        }
        return lv1DistributionDO;
    }

    /**
     * 查询团长信息集合
     */
    @Override
    public List<DistributionVO> getdistributionVO(String memberIdss){
        String sql = "select *,member_id_lv1 lv1_id,member_id_lv2 lv2_id from es_distribution where member_id in(" + memberIdss + ") ";
        return daoSupport.queryForList(sql, DistributionVO.class);
    }


    @Override
    public void updateDistributionStatus(String distributionIds, Integer status){
        if(StringUtil.isEmpty(distributionIds)){
        throw new RuntimeException("请勾选需要启用或禁用的团长");
        }
        List<DistributionVO> list = this.getdistributionVO(distributionIds);
        for (DistributionVO distributionVO : list){
            if(distributionVO != null){
                String sql = "update es_distribution set status = ? ,team_name = null where member_id = ? ";
                daoSupport.execute(sql, status, distributionVO.getMemberId());
            }
        }
    }

    @Override
    public void handleShareRelationship(Integer currentMemberId, Integer sharerMemberId) {
        try{
            // 处理抢占逻辑 如果关系过期了 就更新一级分销为分享人
            DistributionDO distributionDO = getDistributorByMemberId(currentMemberId);
            List<DistributionRelationshipVO> distributionRelationshipVOList = new ArrayList<>();
            // 只有非团长才需要切换上级
            if (distributionDO != null && distributionDO.getAuditStatus() != 2) {
                // 判断上级是否为空  如果为空 表示可以切换一个新的上级
                Integer memberIdLv1 = distributionDO.getMemberIdLv1();
                if(memberIdLv1 == null){
                    logger.debug("切换新的上级分销为" + sharerMemberId);
                    DistributionDO shareDistributionDO = getDistributorByMemberId(sharerMemberId);
                    distributionDO.setMemberIdLv1(sharerMemberId);
                    distributionDO.setMemberIdLv2(shareDistributionDO.getMemberIdLv1());
                    distributionDO.setLv1CreateTime(DateUtil.getDateline());
                    distributionDO.setLv1ExpireTime(DateUtil.getDateline() + DistributionConstants.EXPIRE_TIME);
                    edit(distributionDO);

                    // 保存现在团长信息 source = 3 系统自动
                    DistributionRelationshipVO nowDistributionRelationshipVO = buildDistributionRelationshipVO(currentMemberId,
                            sharerMemberId, "团长绑定",3,  "点击分享链接绑定");
                    // 保存现在 会员上级团长记录
                    distributionRelationshipVOList.add(nowDistributionRelationshipVO);
                }else{
                    // 新的邀请人和旧的如果是同一个人就不用管了
                    if(!sharerMemberId.equals(memberIdLv1)){
                        // 查出原来的上级 如果不是团长考虑切换到新人
                        DistributionDO lv1DistributionDO = getDistributorByMemberId(memberIdLv1);
                        if(lv1DistributionDO != null && (lv1DistributionDO.getAuditStatus() != 2 || lv1DistributionDO.getStatus() != 1)){
                            // 再查询新分享的人是否是团长
                            DistributionDO shareDistributionDO = getDistributorByMemberId(sharerMemberId);
                            if(shareDistributionDO != null && shareDistributionDO.getAuditStatus() == 2 && shareDistributionDO.getStatus() == 1){

                                // 保存历史团长信息 source = 3 系统自动
                                DistributionRelationshipVO lastDistributionRelationshipVO = buildDistributionRelationshipVO(currentMemberId,
                                        lv1DistributionDO.getMemberId(),"团长解绑",3,  null);
                                distributionRelationshipVOList.add(lastDistributionRelationshipVO);

                                logger.debug("切换上级分销:" + memberIdLv1 + "切换为" + sharerMemberId);
                                distributionDO.setMemberIdLv1(sharerMemberId);
                                distributionDO.setMemberIdLv2(shareDistributionDO.getMemberIdLv1());
                                distributionDO.setLv1CreateTime(DateUtil.getDateline());
                                distributionDO.setLv1ExpireTime(DateUtil.getDateline() + DistributionConstants.EXPIRE_TIME);
                                edit(distributionDO);

                                // 保存现在团长信息 source = 3 系统自动
                                DistributionRelationshipVO nowDistributionRelationshipVO = buildDistributionRelationshipVO(currentMemberId,
                                        sharerMemberId, "团长绑定",3, "点击分享链接绑定");
                                // 保存现在 会员上级团长记录
                                distributionRelationshipVOList.add(nowDistributionRelationshipVO);

                            }
                        }
                    }else{
                        // 如果lv1是同一个人  但是lv2是空的 更新一下上级团长
                        Integer memberIdLv2 = distributionDO.getMemberIdLv2();
                        if(memberIdLv2 == null){
                            DistributionDO shareDistributionDO = getDistributorByMemberId(sharerMemberId);
                            if(shareDistributionDO != null && shareDistributionDO.getMemberIdLv1() != null){
                                distributionDO.setMemberIdLv2(shareDistributionDO.getMemberIdLv1());
                                edit(distributionDO);
                            }
                        }
                    }
                }
                amqpTemplate.convertAndSend(AmqpExchange.DISTIRBUTION_BINDING_MESSAGE,
                        AmqpExchange.DISTIRBUTION_BINDING_MESSAGE + "_ROUTING",
                        distributionRelationshipVOList);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public Integer getTeamName(Integer provinceId) {
        // 查询,现在团长审核通过的并且没有被禁用 查询团号最大值 取第一个
        String sql = " SELECT  (Substring(team_name,1,CHAR_LENGTH(team_name)-1)+0) as team_name from es_distribution d where province_id = ? AND audit_status = 2 " +
                " and team_name < 1000 ORDER BY team_name DESC LIMIT 1 ";
        return daoSupport.queryForInt(sql, provinceId)+1;
    }

    /**
     * 查询团号是否在该地区已存在
     */
    @Override
    public  Boolean queryTeamNameNum(DistributionDO distributionDO){
        String teamName = distributionDO.getTeamName();
        Integer provinceId = distributionDO.getProvinceId();
        Integer cityId = distributionDO.getCityId();
        String sql = " select * from es_distribution where team_name = ? and province_id = ? and city_id = ? ";
        List<DistributionDO> distributionDOS = daoSupport.queryForList(sql, DistributionDO.class, teamName, provinceId, cityId);
        if(IDataUtils.isNotEmpty(distributionDOS)){
            return false;
        }
        return true;
    }

    /**
     * 修改上级团长
     */
    @Override
    public void updateSuperiorDistribution(Integer memberId,String mobileOrInvitationCode){
        // 根据手机号或邀请码查询需要修改的团长
        StringBuffer sql = new StringBuffer(" SELECT d.* from es_distribution d " +
                " LEFT JOIN es_member m on d.member_id = m.member_id where 1=1 ");
        Integer mobileOrInvitationCodeInt = 0;
        DistributionVO distributionVO = null;
        if(StringUtil.notEmpty(mobileOrInvitationCode)){
            // 判断 传来的参数长度是否大于10 大于10是手机号,不大于10 是邀请码
            if(mobileOrInvitationCode.length() > 10){
                sql.append(" and m.mobile = ? ");
                distributionVO = daoSupport.queryForObject(sql.toString(), DistributionVO.class, mobileOrInvitationCode);
            }else{
                sql.append(" and d.invite_code = ? ");
                mobileOrInvitationCodeInt = Integer.parseInt(mobileOrInvitationCode);
                distributionVO = daoSupport.queryForObject(sql.toString(), DistributionVO.class, mobileOrInvitationCodeInt);
            }
        }
        if(distributionVO == null){
            throw  new RuntimeException("没有找到团长信息！");
        }
        if(distributionVO.getAuditStatus() != 2 || distributionVO.getStatus() !=1){
            throw  new RuntimeException("团长没有通过审核或团长被禁用了！");
        }
       // 修改上级团长信息 source = 2 用户更改
       updateNormalMemberLv1MemberId(memberId.toString(), distributionVO.getMemberId(),2);

    }

    @Override
    public Member getDistributionMemberByMemberId(Integer memberId) {
        String sql = "SELECT m.* from es_distribution d LEFT JOIN es_member m on d.member_id = m.member_id where d.member_id = ? AND d.audit_status = 2 AND d.`status` = 1 ";
        return daoSupport.queryForObject(sql,Member.class,memberId);
    }

    /**
     * 添加团长记录
     * Integer memberId,Integer distributionMemberId,String operationType,Integer source,String operationDescribe
     *
     */
    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addDistributionRelationshipVO(List<DistributionRelationshipVO> distributionRelationshipVOList){
        for (DistributionRelationshipVO distributionRelationshipVO : distributionRelationshipVOList) {
            Integer memberId = distributionRelationshipVO.getMemberId();
            Integer memberLv1Id = distributionRelationshipVO.getMemberLv1Id();
            String operationDescribe = distributionRelationshipVO.getOperationDescribe();
            Integer source = distributionRelationshipVO.getSource();
            String operationMode = "后台修改";
            switch (source){
                case 2:
                    operationMode = "用户更换";
                    operationDescribe = "用户主动更换";
                    break;
                case 3:
                    operationMode = "系统自动";
                    break;
            }
            // 记录历史团长信息
            Member member = memberManager.getModel(memberLv1Id);
            distributionRelationshipVO.setMemberLv1Mobile(member.getMobile());
            distributionRelationshipVO.setOperationMode(operationMode);
            distributionRelationshipVO.setCreateTime(DateUtil.getDateline());

            // 查询描述
            DistributionRelationshipDO getDistributionRelationshipDO = getDistributionRelationshipDO(memberId);
            if(getDistributionRelationshipDO != null){
                if(StringUtil.notEmpty(operationDescribe)){
                    distributionRelationshipVO.setOperationDescribe(operationDescribe);
                }else {
                    distributionRelationshipVO.setOperationDescribe(getDistributionRelationshipDO.getOperationDescribe());
                }
            }else{
                distributionRelationshipVO.setOperationDescribe(operationDescribe);
            }

            DistributionRelationshipDO distributionRelationshipDO = new DistributionRelationshipDO();
            BeanUtil.copyProperties(distributionRelationshipVO,distributionRelationshipDO);
            daoSupport.insert(distributionRelationshipDO);
        }

    }

    /**
     * 查询会员团长记录中最新一条的描述
     */
    public DistributionRelationshipDO getDistributionRelationshipDO(Integer memberId){
        String sql ="SELECT * from es_distribution_relationship where member_id = ? ORDER BY id DESC ";
        return daoSupport.queryForObject(sql,DistributionRelationshipDO.class,memberId);
    }


    /**
     * 查询会员团长记录
     */
    @Override
    public List<DistributionRelationshipVO> getDistributionRelationshipVOByMemberId(Integer memberId){
        String sql ="SELECT d.*,m.real_name as distribution_name from es_distribution_relationship d LEFT JOIN es_member m ON d.member_lv1_id = m.member_id  where d.member_id = ? ORDER BY d.id DESC";
        return daoSupport.queryForList(sql,DistributionRelationshipVO.class,memberId);
    }


    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void changeDistributionRelationship(Integer oldMemberId, Integer newMemberId) {
        // 查询老会员的团长关系 更新到新会员团长信息中
        DistributionDO oldDistributionDO = getDistributorByMemberId(oldMemberId);
        DistributionDO newDistributionDO = queryNewRegisterDistributionDO(newMemberId);
        newDistributionDO.setMemberIdLv1(oldDistributionDO.getMemberIdLv1());
        newDistributionDO.setMemberIdLv2(oldDistributionDO.getMemberIdLv2());
        newDistributionDO.setAuditStatus(oldDistributionDO.getAuditStatus());
        newDistributionDO.setAuditTime(oldDistributionDO.getAuditTime());
        newDistributionDO.setApplyReason(oldDistributionDO.getApplyReason());
        newDistributionDO.setAuditRemark(oldDistributionDO.getAuditRemark());
        newDistributionDO.setStatus(oldDistributionDO.getStatus());
        newDistributionDO.setLv1CreateTime(oldDistributionDO.getLv1CreateTime());
        newDistributionDO.setLv1ExpireTime(oldDistributionDO.getLv1ExpireTime());
        newDistributionDO.setLastOrderTime(oldDistributionDO.getLastOrderTime());
        newDistributionDO.setLv1InviteCode(oldDistributionDO.getLv1InviteCode());
        newDistributionDO.setProvince(oldDistributionDO.getProvince());
        newDistributionDO.setCity(oldDistributionDO.getCity());
        newDistributionDO.setCounty(oldDistributionDO.getCounty());
        newDistributionDO.setSettleMode(oldDistributionDO.getSettleMode());
        newDistributionDO.setBusinessType(oldDistributionDO.getBusinessType());
        edit(newDistributionDO);

        // 更新粉丝关系
        this.daoSupport.execute("update es_distribution set member_id_lv1 = ?, member_id_lv2 = ?, lv1_invite_code = ? where member_id_lv1 = ?",
                newMemberId, newDistributionDO.getMemberIdLv1(), newDistributionDO.getInviteCode(), oldMemberId);
    }


    // 新创建的用户不一定能马上查询到 需要等mq执行完
    private DistributionDO queryNewRegisterDistributionDO(Integer memberId){
        DistributionDO distribution = getDistributorByMemberId(memberId);
        int time = 1;
        while(distribution == null){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            distribution = getDistributorByMemberId(memberId);
            time++;
            if(time > 5){
                break;
            }
        }
        return distribution;
    }

    @Override
    public DistributionRelationshipVO buildDistributionRelationshipVO(Integer currentMemberId,Integer memberLv1,String operationType,
                                                                      Integer source, String operationDescribe){
        // 保存会员团长记录
        DistributionRelationshipVO distributionRelationshipVO = new DistributionRelationshipVO();
        distributionRelationshipVO.setMemberId(currentMemberId);
        // 现在团长的会员id
        distributionRelationshipVO.setMemberLv1Id(memberLv1);
        distributionRelationshipVO.setOperationType(operationType);
        distributionRelationshipVO.setSource(source);
        distributionRelationshipVO.setOperationDescribe(operationDescribe);
        return distributionRelationshipVO;
    }

    @Override
    public List<DistributionFansOrderVO> getDistributionFansOrderList(Integer memberId) {

        DistributionDO distributor = this.getDistributorByMemberId(memberId);
        if (ObjectUtils.isEmpty(distributor)) {
            return null;
        }
        if (!(distributor.getAuditStatus().equals(2) && distributor.getStatus().equals(1))) {
            return null;
        }
        String sql = "SELECT * from (" +
                "select count(DISTINCT(o.member_id)) today_order_num from es_order o LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                "where o.pay_status='PAY_YES'\n" +
                "and o.order_status != 'CANCELLED'\n" +
                "and o.service_status!='APPLY' and o.create_time> UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE))\n" +
                "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) + INTERVAL 1 DAY) and d.member_id_lv1=?) as a,\n" +
                "(select count(DISTINCT(o.member_id)) week_order_num from es_order o LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                "where o.pay_status='PAY_YES'\n" +
                "and o.order_status != 'CANCELLED'\n" +
                "and o.service_status!='APPLY' \n" +
                "and o.create_time >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 7) \n" +
                "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE)) \n" +
                "and d.member_id_lv1=?) as b,\n" +
                "(select count(DISTINCT(o.member_id)) two_week_order_num from es_order o LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                "where o.pay_status='PAY_YES'\n" +
                "and o.order_status != 'CANCELLED'\n" +
                "and o.service_status!='APPLY' \n" +
                "and o.create_time >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 14) \n" +
                "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) -7) \n" +
                "and d.member_id_lv1=?) as c,\n" +
                "(select count(DISTINCT(o.member_id)) three_week_order_num from es_order o LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                "where o.pay_status='PAY_YES'\n" +
                "and o.order_status != 'CANCELLED'\n" +
                "and o.service_status!='APPLY' \n" +
                "and o.create_time >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 21) \n" +
                "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) -14) \n" +
                "and d.member_id_lv1=?) as d";

        Map map = daoSupport.queryForMap(sql, memberId, memberId, memberId, memberId);
        List<DistributionFansOrderVO> distributionFansOrderVOList = new ArrayList<>();
        this.buildDistributionFansOrderVO(map, distributionFansOrderVOList);

        String queryLastVisitDaySql = "SELECT * from(\n" +
                "SELECT count(0) silence_three_day_num from(\n" +
                "select d.member_id, v.member_name, max(v.visit_day) visit_day from es_distribution d\n" +
                "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                "where UNIX_TIMESTAMP(a.visit_day) < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 3)\n" +
                "and UNIX_TIMESTAMP(a.visit_day) >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 7)) as a,\n" +
                "(SELECT count(0) silence_one_week_num from(\n" +
                "select d.member_id, v.member_name, max(v.visit_day) visit_day from es_distribution d\n" +
                "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                "where UNIX_TIMESTAMP(a.visit_day) < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 7)\n" +
                "and UNIX_TIMESTAMP(a.visit_day) >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 14)) as b,\n" +
                "(SELECT count(0) silence_two_week_num from(\n" +
                "select d.member_id, v.member_name, max(v.visit_day) visit_day from es_distribution d\n" +
                "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                "where UNIX_TIMESTAMP(a.visit_day) < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 14)\n" +
                "and UNIX_TIMESTAMP(a.visit_day) >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 21)) as c,\n" +
                "(SELECT count(0) silence_three_week_num from(\n" +
                "select d.member_id, v.member_name, max(v.visit_day) visit_day from es_distribution d\n" +
                "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                "where UNIX_TIMESTAMP(a.visit_day) < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 21)\n" +
                "and UNIX_TIMESTAMP(a.visit_day) >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 30)) as d;";

        Map silenceMap = daoSupport.queryForMap(queryLastVisitDaySql, memberId, memberId, memberId, memberId);
        this.buildDistributionFansOrderVO(silenceMap, distributionFansOrderVOList);

        return distributionFansOrderVOList;
    }

    private void buildDistributionFansOrderVO(Map map, List<DistributionFansOrderVO> distributionFansOrderVOList) {

        Set set = map.keySet();

        for (Object key : set) {
            DistributionFansOrderVO distributionFansOrderVO = new DistributionFansOrderVO();
            distributionFansOrderVO.setDataType((String) key);
            distributionFansOrderVO.setNum(Integer.parseInt(map.get(key).toString()));
            distributionFansOrderVOList.add(distributionFansOrderVO);
        }
    }

    @Override
    public Page queryFansDataByType(String fans_data_key, Integer memberId, Integer pageNo, Integer pageSize) {

        String sql;

        if (StringUtil.isEmpty(fans_data_key)) {
            sql = "select m.face, m.nickname, d.lv1_create_time, d.last_order_time, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from \n" +
                    "es_distribution d LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                    "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                    "where d.member_id_lv1=? GROUP BY d.member_id";
            return daoSupport.queryForPage(sql, pageNo, pageSize, FansDataVO.class, memberId);
        }

        switch (FansDataKeyEnum.valueOf(fans_data_key)) {
            case today_order_num:
                sql = "select m.face, m.nickname, d.lv1_create_time, d.last_order_time, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_order o \n" +
                        "LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where o.pay_status='PAY_YES' and o.order_status != 'CANCELLED' and d.member_id_lv1=? \n" +
                        "and o.service_status!='APPLY' and o.create_time> UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE))\n" +
                        "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) + INTERVAL 1 DAY) GROUP BY d.member_id";
                break;
            case week_order_num:
                sql = "select m.face, m.nickname, d.lv1_create_time, d.last_order_time, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_order o \n" +
                        "LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where o.pay_status='PAY_YES' and o.order_status != 'CANCELLED' and d.member_id_lv1=? \n" +
                        "and o.service_status!='APPLY' and o.create_time >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 7) \n" +
                        "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE))  GROUP BY d.member_id";
                break;
            case two_week_order_num:
                sql = "select m.face, m.nickname, d.lv1_create_time, d.last_order_time, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_order o \n" +
                        "LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where o.pay_status='PAY_YES' and o.order_status != 'CANCELLED' and d.member_id_lv1=? \n" +
                        "and o.service_status!='APPLY' and o.create_time >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 14) \n" +
                        "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) -7)   GROUP BY d.member_id";
                break;
            case three_week_order_num:
                sql = "select m.face, m.nickname, d.lv1_create_time, d.last_order_time, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_order o \n" +
                        "LEFT JOIN es_distribution d on o.member_id=d.member_id\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where o.pay_status='PAY_YES' and o.order_status != 'CANCELLED' and d.member_id_lv1=? \n" +
                        "and o.service_status!='APPLY' and o.create_time >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 21) \n" +
                        "and o.create_time < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) -14)   GROUP BY d.member_id";
                break;
            case silence_three_day_num:
                sql = "SELECT a.face, a.nickname, a.last_visit_day, d.lv1_create_time, d.last_order_time from(\n" +
                        "select d.member_id, m.nickname, m.face, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_distribution d\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                        "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                        "where a.last_visit_day < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 3)\n" +
                        "and a.last_visit_day >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 7)";
                break;
            case silence_one_week_num:
                sql = "SELECT a.face, a.nickname, a.last_visit_day, d.lv1_create_time, d.last_order_time from(\n" +
                        "select d.member_id, m.nickname, m.face, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_distribution d\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                        "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                        "where a.last_visit_day < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 7)\n" +
                        "and a.last_visit_day >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 14)";
                break;
            case silence_two_week_num:
                sql = "SELECT a.face, a.nickname, a.last_visit_day, d.lv1_create_time, d.last_order_time from(\n" +
                        "select d.member_id, m.nickname, m.face, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_distribution d\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                        "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                        "where a.last_visit_day < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 14)\n" +
                        "and a.last_visit_day >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 21)";
                break;
            case silence_three_week_num:
                sql = "SELECT a.face, a.nickname, a.last_visit_day, d.lv1_create_time, d.last_order_time from(\n" +
                        "select d.member_id, m.nickname, m.face, UNIX_TIMESTAMP(max(v.visit_day)) last_visit_day from es_distribution d\n" +
                        "LEFT JOIN es_member_pv v on d.member_id=v.member_id\n" +
                        "LEFT JOIN es_member m on d.member_id=m.member_id\n" +
                        "where d.member_id_lv1=? GROUP BY d.member_id) as a\n" +
                        "LEFT JOIN es_distribution d on a.member_id=d.member_id\n" +
                        "where a.last_visit_day < UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 21)\n" +
                        "and a.last_visit_day >= UNIX_TIMESTAMP(CAST(SYSDATE()AS DATE) - 30)";
                break;

            default: throw new ServiceException("500", "系统异常，请联系客服");
        }

        return daoSupport.queryForPage(sql, pageNo, pageSize, FansDataVO.class, memberId);
    }
}
